import { Injectable, Logger } from '@nestjs/common';
import { ApiProvider, TargetProvider } from '../interfaces/api-adapter.interface';
import { GenericForwardingService } from '../core/generic-forwarding.service';
import { AdapterRegistryService } from '../core/adapter-registry.service';
import { ProxyConfigService } from '../config/proxy.config';
import { CreateMessageDto, MessageResponseDto, CountTokensDto, CountTokensResponseDto } from '../dto/messages.dto';
import { AnthropicRequestLog } from '../interfaces/anthropic-api.interface';
import { CopilotRequestLoggerService, RequestContext, PhaseData, FieldChange } from './copilot-request-logger.service';
import { FieldDiffTrackerService } from './field-diff-tracker.service';
import { RequestPhase, RequestStatus, MappingType } from '../../database/entities/copilot-types';

/**
 * 增强的转发服务
 * 保持向后兼容的同时，提供新的多 API 转发能力
 */
@Injectable()
export class EnhancedForwardingService {
  private readonly logger = new Logger(EnhancedForwardingService.name);

  constructor(
    private readonly genericForwarding: GenericForwardingService,
    private readonly adapterRegistry: AdapterRegistryService,
    private readonly configService: ProxyConfigService,
    private readonly copilotLogger: CopilotRequestLoggerService,
    private readonly fieldDiffTracker: FieldDiffTrackerService
  ) {}

  /**
   * 转发 Anthropic 消息请求（向后兼容）
   */
  async forwardMessageRequest(
    createMessageDto: CreateMessageDto, 
    requestInfo: Partial<AnthropicRequestLog>
  ): Promise<MessageResponseDto> {
    const startTime = Date.now();
    
    // 创建请求上下文
    const requestContext: RequestContext = {
      requestId: this.copilotLogger.createRequestContext(),
      userId: requestInfo.userId,
      userIp: requestInfo.ip,
      userAgent: requestInfo.userAgent,
      modelName: createMessageDto.model,
      isStreaming: createMessageDto.stream || false,
      hasTools: !!(createMessageDto.tools && createMessageDto.tools.length > 0)
    };
    
    const requestId = await this.copilotLogger.createRequestLog(requestContext);
    
    try {
      // 阶段1：记录客户端请求
      await this.copilotLogger.logClientRequest(requestId, {
        headers: requestInfo.headers || {},
        body: createMessageDto,
        method: 'POST',
        url: '/v1/messages',
        timestamp: new Date(startTime)
      });
      
      const result = await this.forwardApiRequestWithLogging(
        ApiProvider.ANTHROPIC,
        TargetProvider.COPILOT,
        createMessageDto,
        { ...requestInfo, requestId }
      );
      
      // 阶段4：记录客户端响应
      await this.copilotLogger.logClientResponse(requestId, {
        headers: { 'content-type': 'application/json' },
        body: result,
        status: 200,
        timestamp: new Date()
      });
      
      return result;
    } catch (error) {
      // 记录错误
      await this.copilotLogger.logError(
        requestId,
        error,
        RequestPhase.CLIENT_RESPONSE,
        { 
          model: createMessageDto.model, 
          provider: ApiProvider.ANTHROPIC,
          originalRequest: createMessageDto
        }
      );
      
      throw error;
    }
  }

  /**
   * 转发 Anthropic 令牌计数请求（向后兼容）
   */
  async forwardCountTokensRequest(
    countTokensDto: CountTokensDto,
    requestInfo: Partial<AnthropicRequestLog>
  ): Promise<CountTokensResponseDto> {
    const requestId = this.copilotLogger.createRequestContext();
    
    // 对于 token 计数，我们可以使用本地估算或发送到对应的 API
    const adapter = this.adapterRegistry.getAdapter(ApiProvider.ANTHROPIC, TargetProvider.COPILOT);
    if (!adapter) {
      const error = new Error('Anthropic to Copilot adapter not found');
      
      await this.copilotLogger.logErrorLegacy(
        requestId,
        'EnhancedForwardingService',
        'Adapter not found for token counting',
        error,
        {
          provider: ApiProvider.ANTHROPIC,
          target: TargetProvider.COPILOT,
          operation: 'count_tokens'
        }
      );
      
      throw error;
    }

    // 使用适配器的本地估算功能
    const totalText = this.extractTextFromCountTokensRequest(countTokensDto);
    const estimatedTokens = this.estimateTokenCount(totalText);
    
    // 简化的控制台日志
    this.logger.log(`Token count estimated: ${estimatedTokens}`);
    
    // 记录Token计数完成（使用简化日志）
    this.logger.log(`Token count estimation completed: ${estimatedTokens} tokens for ${totalText.length} characters`);
    
    return {
      input_tokens: estimatedTokens
    };
  }

  /**
   * 带有详细日志记录的API转发方法
   */
  private async forwardApiRequestWithLogging(
    provider: ApiProvider,
    target: TargetProvider,
    request: any,
    requestInfo?: any
  ): Promise<any> {
    const requestId = requestInfo?.requestId;
    const conversionStartTime = Date.now();
    
    try {
      // 获取适配器
      const adapter = this.adapterRegistry.getAdapter(provider, target);
      if (!adapter) {
        throw new Error(`Adapter not found for ${provider} -> ${target}`);
      }

      // 阶段2：记录转换开始和Copilot请求
      const genericRequest = await adapter.convertToGeneric(request);
      const copilotRequest = await adapter.convertFromGeneric(genericRequest);
      
      // 分析字段变化：客户端请求 -> Copilot请求
      const fieldChanges = this.fieldDiffTracker.compareObjects(
        request,
        copilotRequest,
        {
          ignoredFields: ['timestamp', '__typename'],
          sensitiveFields: ['token', 'key', 'authorization']
        }
      );

      // 记录字段映射变化
      if (fieldChanges.length > 0) {
        await this.copilotLogger.logFieldMappings(
          requestId,
          RequestPhase.CLIENT_REQUEST,
          RequestPhase.COPILOT_REQUEST,
          fieldChanges, // 直接传递，因为格式已经匹配
          adapter.constructor.name
        );
      }

      await this.copilotLogger.logCopilotRequest(requestId, {
        headers: this.buildCopilotHeaders(requestInfo),
        body: copilotRequest,
        method: 'POST',
        url: '/chat/completions',
        timestamp: new Date()
      });

      // 调用实际的API
      const apiCallStartTime = Date.now();
      const result = await this.forwardApiRequest(provider, target, request, requestInfo);
      const apiCallEndTime = Date.now();

      // 阶段3：记录Copilot响应
      await this.copilotLogger.logCopilotResponse(requestId, {
        headers: { 'content-type': 'application/json' },
        body: result,
        status: 200,
        timestamp: new Date(apiCallEndTime)
      });

      // 分析字段变化：Copilot响应 -> 客户端响应
      const responseFieldChanges = this.fieldDiffTracker.compareObjects(
        result,
        result, // 这里应该是转换后的响应，暂时用原响应
        {
          ignoredFields: ['timestamp', 'request_id'],
          sensitiveFields: []
        }
      );

      if (responseFieldChanges.length > 0) {
        await this.copilotLogger.logFieldMappings(
          requestId,
          RequestPhase.COPILOT_RESPONSE,
          RequestPhase.CLIENT_RESPONSE,
          responseFieldChanges, // 直接传递
          adapter.constructor.name
        );
      }

      return result;
    } catch (error) {
      await this.copilotLogger.logError(
        requestId,
        error,
        RequestPhase.COPILOT_REQUEST,
        { provider, target, conversionDuration: Date.now() - conversionStartTime }
      );
      throw error;
    }
  }

  /**
   * 构建Copilot请求头
   */
  private buildCopilotHeaders(requestInfo: any): Record<string, any> {
    return {
      'content-type': 'application/json',
      'user-agent': requestInfo?.userAgent || 'Copilot-Proxy/1.0.0',
      'x-request-id': requestInfo?.requestId,
      // 其他必要的头部信息
    };
  }

  /**
   * 映射差异类型到映射类型
   */
  private mapDiffTypeToMappingType(diffType: string): MappingType {
    const mappings = {
      'field_added': MappingType.FIELD_ADDED,
      'field_removed': MappingType.FIELD_REMOVED,
      'field_modified': MappingType.FIELD_MODIFIED,
      'field_renamed': MappingType.FIELD_RENAMED,
      'type_changed': MappingType.TYPE_CHANGED,
      'value_transformed': MappingType.VALUE_TRANSFORMED,
      'structure_changed': MappingType.STRUCTURE_CHANGED
    };
    return mappings[diffType as keyof typeof mappings] || MappingType.VALUE_TRANSFORMED;
  }

  /**
   * 生成转换规则描述
   */
  private generateTransformationRule(change: any): string {
    switch (change.type) {
      case 'field_added':
        return `添加字段: ${change.toFieldName}`;
      case 'field_removed':
        return `移除字段: ${change.fromFieldName}`;
      case 'field_renamed':
        return `重命名字段: ${change.fromFieldName} -> ${change.toFieldName}`;
      case 'type_changed':
        return `类型变更: ${change.fromType} -> ${change.toType}`;
      case 'value_transformed':
        return `值转换: ${JSON.stringify(change.fromValue).substring(0, 50)} -> ${JSON.stringify(change.toValue).substring(0, 50)}`;
      default:
        return `字段变化: ${change.path}`;
    }
  }

  /**
   * 通用 API 转发方法
   */
  async forwardApiRequest(
    provider: ApiProvider,
    target: TargetProvider,
    request: any,
    requestInfo?: any
  ): Promise<any> {
    const requestId = requestInfo?.requestId || this.copilotLogger.createRequestContext();
    const forwardingStartTime = Date.now();
    
    try {
      // 记录转发开始（简化日志）
      this.logger.log(`Starting generic API request forwarding: ${provider} -> ${target}`);
      
      const copilotConfig = await this.configService.getCopilotConfig();
      
      const config = {
        baseUrl: copilotConfig.apiUrl,
        timeout: copilotConfig.timeout,
        retryAttempts: copilotConfig.retryAttempts,
        integrationId: 'jetbrains-chat',
        lspVersion: '1.348.0',
        pluginVersion: 'copilot-intellij/1.5.52-241',
        editorVersion: 'JetBrains-IU/241.14494.240',
        machineId: '94d35625a61fd8f9fa14b64f9bf5c1cafe88359acc2dfa71fc527c04ec688653',
        sessionId: '0f8362b0-6939-4bc4-b1c5-0023da37a1461754191375398',
        userAgent: copilotConfig.userAgent
      };

      const userInfo = {
        ip: requestInfo?.ip || '127.0.0.1',
        userAgent: requestInfo?.userAgent || 'API-Client',
        headers: requestInfo?.headers || {},
        requestId // 传递requestId到下游服务
      };

      // 记录配置信息（简化日志）
      this.logger.debug(`Forwarding request to ${config.baseUrl} with timeout ${config.timeout}ms`);
      
      const result = await this.genericForwarding.forwardRequest(
        provider,
        target,
        request,
        userInfo,
        config
      );

      if (!result.success) {
        await this.copilotLogger.logErrorLegacy(
          requestId,
          'EnhancedForwardingService',
          'Generic forwarding returned unsuccessful result',
          result.error,
          {
            provider,
            target,
            hasResponse: !!result.response
          }
        );
        
        throw result.error;
      }
      
      const forwardingDuration = Date.now() - forwardingStartTime;
      
      // 记录转发成功（简化日志）
      this.logger.log(`Generic API request forwarding completed successfully in ${forwardingDuration}ms`);

      return result.response;
    } catch (error) {
      const forwardingDuration = Date.now() - forwardingStartTime;
      
      await this.copilotLogger.logErrorLegacy(
        requestId,
        'EnhancedForwardingService',
        'Generic API request forwarding failed',
        error,
        {
          provider,
          target,
          duration: forwardingDuration
        }
      );
      
      throw error;
    }
  }

  /**
   * 批量转发请求
   */
  async forwardBatchRequests(
    provider: ApiProvider,
    target: TargetProvider,
    requests: any[],
    requestInfo?: any
  ): Promise<any[]> {
    const copilotConfig = await this.configService.getCopilotConfig();
    
    const config = {
      baseUrl: copilotConfig.apiUrl,
      timeout: copilotConfig.timeout,
      retryAttempts: copilotConfig.retryAttempts
    };

    const userInfo = {
      ip: requestInfo?.ip || '127.0.0.1',
      userAgent: requestInfo?.userAgent || 'API-Client',
      headers: requestInfo?.headers || {}
    };

    const results = await this.genericForwarding.forwardBatch(
      provider,
      target,
      requests,
      userInfo,
      config
    );

    return results.map(result => {
      if (!result.success) {
        throw result.error;
      }
      return result.response;
    });
  }

  /**
   * 检查转发服务健康状态（增强版）
   */
  async checkForwardingHealth(): Promise<any> {
    const genericHealth = await this.genericForwarding.checkHealth();
    const mode = this.configService.getProxyMode();
    const copilotConfig = await this.configService.getCopilotConfig();
    
    return {
      ...genericHealth,
      mode: mode,
      copilotConfig: {
        apiUrl: copilotConfig.apiUrl,
        hasGithubToken: !!copilotConfig.githubToken,
        hasAuthToken: !!copilotConfig.authToken
      },
      supportedProviders: [ApiProvider.ANTHROPIC, ApiProvider.OPENAI],
      supportedTargets: [TargetProvider.COPILOT]
    };
  }

  /**
   * 获取支持的 API 转发路径
   */
  getSupportedRoutes(): Array<{ provider: ApiProvider; target: TargetProvider; description: string }> {
    const routes = this.genericForwarding.getSupportedRoutes();
    
    return routes.map(route => ({
      ...route,
      description: this.getRouteDescription(route.provider, route.target)
    }));
  }

  /**
   * 检查是否支持指定的转发路径
   */
  isRouteSupported(provider: ApiProvider, target: TargetProvider): boolean {
    return this.adapterRegistry.isSupported(provider, target);
  }

  /**
   * 从 CountTokens 请求中提取文本
   */
  private extractTextFromCountTokensRequest(countTokensDto: CountTokensDto): string {
    let totalText = '';
    
    // 从系统提示计算
    if (countTokensDto.system) {
      if (typeof countTokensDto.system === 'string') {
        totalText += countTokensDto.system;
      }
    }

    // 从消息计算
    countTokensDto.messages.forEach(message => {
      if (typeof message.content === 'string') {
        totalText += message.content;
      } else if (Array.isArray(message.content)) {
        totalText += message.content
          .filter(block => block.type === 'text')
          .map(block => block.text || '')
          .join(' ');
      }
    });

    return totalText;
  }

  /**
   * 估算令牌数量
   */
  private estimateTokenCount(text: string): number {
    if (!text) return 0;
    
    // 简单估算：英文约4字符=1token，中文约1.5字符=1token
    const englishChars = (text.match(/[a-zA-Z0-9\s]/g) || []).length;
    const chineseChars = (text.match(/[\u4e00-\u9fff]/g) || []).length;
    const otherChars = text.length - englishChars - chineseChars;
    
    const estimatedTokens = Math.ceil(
      englishChars / 4 + 
      chineseChars / 1.5 + 
      otherChars / 3
    );

    return Math.max(1, estimatedTokens);
  }

  /**
   * 获取路径描述
   */
  private getRouteDescription(provider: ApiProvider, target: TargetProvider): string {
    const descriptions: Record<string, string> = {
      [`${ApiProvider.ANTHROPIC}->${TargetProvider.COPILOT}`]: 'Forward Anthropic Claude API to GitHub Copilot',
      [`${ApiProvider.OPENAI}->${TargetProvider.COPILOT}`]: 'Forward OpenAI GPT API to GitHub Copilot'
    };

    return descriptions[`${provider}->${target}`] || `Forward ${provider} API to ${target}`;
  }
}